home *** CD-ROM | disk | FTP | other *** search
Text File | 1996-09-17 | 35.9 KB | 1,350 lines | [TEXT/MPS ] |
- //========================================================================================
- //
- // File: PRBitmap.cpp
- // Release Version: $ ODF 2 $
- //
- // Copyright: (c) 1993 - 1996 by Apple Computer, Inc., all rights reserved.
- //
- //========================================================================================
-
- #include "FWOS.hpp"
-
- #ifndef SLPALETE_H
- #include "SLPalete.h"
- #endif
-
- #ifndef FWODEXCE_H
- #include "FWODExce.h"
- #endif
-
- #ifndef FWBITMAP_H
- #include "FWBitmap.h"
- #endif
-
- #ifndef PRBITMAP_H
- #include "PRBitmap.h"
- #endif
-
- #ifndef SLGC_H
- #include "SLGC.h"
- #endif
-
- #ifndef FWWINRES_H
- #include "FWWinRes.h"
- #endif
-
- #ifndef FWSTRMRW_H
- #include "FWStrmRW.h"
- #endif
-
- #ifndef FWRESOUR_H
- #include "FWResour.h"
- #endif
-
- #ifndef FWGRUTIL_H
- #include "FWGrUtil.h"
- #endif
-
- #ifndef FWPALETE_H
- #include "FWPalete.h"
- #endif
-
- #ifndef FWSOMENV_H
- #include "FWSOMEnv.h"
- #endif
-
- #ifndef PRGRUTIL_H
- #include "PRGrUtil.h"
- #endif
-
- #ifndef FWMEMHLP_H
- #include "FWMemHlp.h"
- #endif
-
- #ifndef FWEXCEPT_H
- #include "FWExcept.h"
- #endif
-
- #if defined(FW_BUILD_WIN) && !defined(FWWINDIB_H)
- #include "FWWinDIB.h"
- #endif
-
- #if defined(FW_BUILD_MAC) && !defined(__PICTUTILS__)
- #include <PictUtils.h>
- #endif
-
- #ifndef PRPICTUR_H
- #include "PRPictur.h"
- #endif
-
- //========================================================================================
- // RunTime Info
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
- #pragma segment FW_Graphics
- #endif
-
- FW_DEFINE_AUTO(FW_CPrivBitmapRep)
-
- //========================================================================================
- // CLASS FW_CPrivBitmapRep
- //========================================================================================
-
- #ifdef FW_BUILD_MAC
-
- // Special Russian value swapping: uses no temporary
-
- #define SWAP(a, b) do { (a) = (a) ^ (b); (b) = (a) ^ (b); (a) = (a) ^ (b); } while(0)
-
- //----------------------------------------------------------------------------------------
- // MacRepackResourceRow
- //----------------------------------------------------------------------------------------
-
- static void MacRepackResourceRow(char* curBuffer, short bitDepth, short resRowBytes)
- {
- short pixelBytes = bitDepth / 8;
-
- if(pixelBytes == 2)
- {
- do
- {
- SWAP(curBuffer[0], curBuffer[1]);
- }
- while((resRowBytes -= pixelBytes) > 0);
- }
- else if(pixelBytes == 4)
- {
- do
- {
- SWAP(curBuffer[0], curBuffer[3]);
- SWAP(curBuffer[1], curBuffer[2]);
- }
- while((resRowBytes -= pixelBytes) > 0);
- }
- }
-
- //----------------------------------------------------------------------------------------
- // MacRepackValue
- //----------------------------------------------------------------------------------------
-
- static void MacRepackValue(short* s)
- {
- char* c = (char*) s;
- SWAP(c[0], c[1]);
- }
-
- static void MacRepackValue(unsigned short* s)
- {
- char* c = (char*) s;
- SWAP(c[0], c[1]);
- }
-
- static void MacRepackValue(long* l)
- {
- char* c = (char*) l;
- SWAP(c[0], c[3]);
- SWAP(c[1], c[2]);
- }
-
- static void MacRepackValue(unsigned long* l)
- {
- char* c = (char*) l;
- SWAP(c[0], c[3]);
- SWAP(c[1], c[2]);
- }
-
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::FW_CPrivBitmapRep
- //----------------------------------------------------------------------------------------
- // From image: will own the bitmap
-
- FW_CPrivBitmapRep::FW_CPrivBitmapRep(short width, short height,
- short pixelSize, FW_Palette palette,
- void* image, long imageSize, short rowBytes) :
- fOwnBitmap(TRUE),
- fPlatformBitmap(NULL)
- {
- #ifdef FW_BUILD_MAC
- fLockCount = 0;
- fPixMapHandle = NULL;
- #endif
- #ifdef FW_BUILD_WIN
- fUserColorDepth = 0;
- fWinPalette = NULL;
- #endif
-
- PrivMakeBitmap(width, height, pixelSize, palette);
-
- if (image != NULL)
- SetImage(image, imageSize, rowBytes);
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::FW_CPrivBitmapRep
- //----------------------------------------------------------------------------------------
- // From platform bitmap: will not own the bitmap
-
- FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_PlatformBitmap platformBitmap) :
- fOwnBitmap(FALSE),
- fPlatformBitmap(platformBitmap)
- {
- #ifdef FW_BUILD_MAC
- fLockCount = 0;
- fPixMapHandle = NULL;
- #endif
- #ifdef FW_BUILD_WIN
- fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
- fWinPalette = NULL;
- #endif
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::FW_CPrivBitmapRep
- //----------------------------------------------------------------------------------------
- // From resources: will own the bitmap
-
- FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_OResourceFile* resourceFile, FW_ResourceID resID) :
- fOwnBitmap(TRUE),
- fPlatformBitmap(NULL)
- {
- #ifdef FW_BUILD_MAC
- fLockCount = 0;
- fPixMapHandle = NULL;
- #endif
- #ifdef FW_BUILD_WIN
- fUserColorDepth = 0;
- fWinPalette = NULL;
- #endif
-
- fPlatformBitmap = NULL;
-
- FW_SOMEnvironment ev;
- FW_PResource resource(ev, resourceFile, resID, FW_kBitmap);
- FW_PResourceSink sink(ev, resource);
- FW_CReadableStream stream(sink);
-
- #ifdef FW_BUILD_WIN
- PrivReadFromStream(stream, FALSE);
- #endif
- #ifdef FW_BUILD_MAC
- PrivReadFromStream(stream, TRUE);
- #endif
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::FW_CPrivBitmapRep
- //----------------------------------------------------------------------------------------
- // From another bitmap: will own the bitmap (a copy is made)
-
- FW_CPrivBitmapRep::FW_CPrivBitmapRep(const FW_CPrivBitmapRep& bitmap, const FW_SRect& srcRect) :
- fOwnBitmap(TRUE),
- fPlatformBitmap(NULL)
- {
- #ifdef FW_BUILD_MAC
- fLockCount = 0;
- fPixMapHandle = NULL;
- #endif
- #ifdef FW_BUILD_WIN
- fUserColorDepth = 0;
- fWinPalette = NULL;
- #endif
-
- FW_CRect bounds;
- bitmap.GetBitmapBounds(bounds);
-
- FW_CRect clipRect = srcRect;
-
- if (clipRect.left < FW_kFixed0)
- clipRect.left = FW_kFixed0;
- else if (clipRect.left > bounds.right)
- clipRect.left = bounds.right;
-
- if (clipRect.top < FW_kFixed0)
- clipRect.top = FW_kFixed0;
- else if (clipRect.top > bounds.bottom)
- clipRect.top = bounds.bottom;
-
- if (clipRect.right > bounds.right)
- clipRect.right = bounds.right;
- else if (clipRect.right < clipRect.left)
- clipRect.right = clipRect.left;
-
- if (clipRect.bottom > bounds.bottom)
- clipRect.bottom = bounds.bottom;
- else if (clipRect.bottom < clipRect.top)
- clipRect.bottom = clipRect.top;
-
- FW_CRect dstRect(FW_kFixed0, FW_kFixed0, clipRect.right - clipRect.left, clipRect.bottom - clipRect.top);
-
- short width, height, rowBytes, pixelSize;
- bitmap.GetBitmapInfo(width, height, rowBytes, pixelSize);
-
- FW_Palette palette = bitmap.GetPalette();
- PrivMakeBitmap(
- FW_FixedToInt(clipRect.right - clipRect.left),
- FW_FixedToInt(clipRect.bottom - clipRect.top), pixelSize, palette);
-
- bitmap.CopyPixels(*this, clipRect, dstRect);
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::~FW_CPrivBitmapRep
- //----------------------------------------------------------------------------------------
-
- FW_CPrivBitmapRep::~FW_CPrivBitmapRep()
- {
- PrivDisposeBitmap();
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::IsEqual
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CPrivBitmapRep::IsEqual(const FW_CPrivBitmapRep& bitmap) const
- {
- return fPlatformBitmap == bitmap.fPlatformBitmap;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::Write
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::Write(FW_CWritableStream& stream, FW_Boolean bDIBFileHeader)
- {
- #ifdef FW_BUILD_MAC
- // Lock the GWorld pixmap
- FW_CPrivMacPixelLock lock(this);
- PixMapHandle pmh = lock.GetPixMapHandle();
-
- short width = (*pmh)->bounds.right;
- short height = (*pmh)->bounds.bottom;
- short bitDepth = (*pmh)->pixelSize;
-
- short resRowBytes = ((width * bitDepth + 31) & ~31) / 8;
- short memRowBytes = (*pmh)->rowBytes & 0x7FFF;
-
- FW_ASSERT(resRowBytes <= memRowBytes);
-
- long imageSize = height * resRowBytes;
-
- // Determine color table size
- int colorTableCount = bitDepth < 16 ? 1 << bitDepth : 0;
- int colorTableSize = colorTableCount * sizeof(RGBQUAD);
-
- // Create a file header
- if(bDIBFileHeader)
- {
- BITMAPFILEHEADER bmfh;
- bmfh.bfType = FW_kWinBitmapSignature;
- bmfh.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
- colorTableSize + imageSize;
- bmfh.bfReserved1 = 0;
- bmfh.bfReserved2 = 0;
- bmfh.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) +
- colorTableSize;
-
- // Byte-swap and write it out
-
- MacRepackValue(&bmfh.bfType);
- MacRepackValue(&bmfh.bfSize);
- MacRepackValue(&bmfh.bfReserved1);
- MacRepackValue(&bmfh.bfReserved2);
- MacRepackValue(&bmfh.bfOffBits);
-
- stream.Write(&bmfh, sizeof(bmfh));
- }
-
- // Create a DIB header
-
- BITMAPINFOHEADER bmih;
-
- bmih.biSize = sizeof(BITMAPINFOHEADER);
- bmih.biWidth = width;
- bmih.biHeight = height;
- bmih.biPlanes = 1;
- bmih.biBitCount = bitDepth;
-
- bmih.biCompression = 0;
- bmih.biSizeImage = imageSize;
-
- bmih.biXPelsPerMeter = 0;
- bmih.biYPelsPerMeter = 0;
- bmih.biClrUsed = 0;
- bmih.biClrImportant = 0;
-
- // Byte-swap and write it out
-
- MacRepackValue(&bmih.biSize);
- MacRepackValue(&bmih.biWidth);
- MacRepackValue(&bmih.biHeight);
- MacRepackValue(&bmih.biPlanes);
- MacRepackValue(&bmih.biBitCount);
- MacRepackValue(&bmih.biCompression);
- MacRepackValue(&bmih.biSizeImage);
- MacRepackValue(&bmih.biXPelsPerMeter);
- MacRepackValue(&bmih.biYPelsPerMeter);
- MacRepackValue(&bmih.biClrUsed);
- MacRepackValue(&bmih.biClrImportant);
-
- stream.Write(&bmih, sizeof(bmih));
-
- // Write the color table (if applicable)
- if(colorTableCount != 0)
- {
- CTabHandle cTabHandle = (*pmh)->pmTable;
- FW_ASSERT(colorTableCount <= (*cTabHandle)->ctSize + 1); // ctSize is count - 1!
-
- for(int i = 0; i < colorTableCount; ++i)
- {
- RGBQUAD quad;
-
- quad.rgbBlue = (*cTabHandle)->ctTable[i].rgb.blue >> 8;
- quad.rgbGreen = (*cTabHandle)->ctTable[i].rgb.green >> 8;
- quad.rgbRed = (*cTabHandle)->ctTable[i].rgb.red >> 8;
- quad.rgbReserved = 0;
-
- stream.Write(&quad, sizeof(quad));
- }
- }
-
- // Finally, do the bits (upside-down)
- char* bitsBuffer = new char[memRowBytes];
-
- FW_TRY
- {
- const char* baseBuffer = ::GetPixBaseAddr(pmh);
- const char* currBuffer = baseBuffer + memRowBytes * (height - 1);
-
- for(int row = height - 1; row >= 0; -- row, currBuffer -= memRowBytes)
- {
- ::BlockMove(currBuffer, bitsBuffer, resRowBytes);
- MacRepackResourceRow(bitsBuffer, bitDepth, resRowBytes);
- stream.Write(bitsBuffer, resRowBytes);
- }
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- delete[] bitsBuffer;
- FW_THROW_SAME();
- }
- FW_CATCH_END
- delete[] bitsBuffer;
- #endif
-
- #ifdef FW_BUILD_WIN
- // Convert to DIB first; use the color depth the user wanted
- FW_WinDIB dib = FW_DIBConvertFromBitmap(fPlatformBitmap, fUserColorDepth, fWinPalette);
-
- FW_TRY
- {
- // Write out the DIB
- FW_DIBSaveToStream(stream, dib, bDIBFileHeader);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- FW_DIBFree(dib);
- FW_THROW_SAME();
- }
- FW_CATCH_END
-
- // Free the DIB
- FW_DIBFree(dib);
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::FW_CPrivBitmapRep
- //----------------------------------------------------------------------------------------
- // From a stream: will own the bitmap
-
- FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_CReadableStream& stream, FW_Boolean bDIBFileHeader) :
- fOwnBitmap(TRUE),
- fPlatformBitmap(NULL)
- {
- #ifdef FW_BUILD_MAC
- fLockCount = 0;
- fPixMapHandle = NULL;
- #endif
- #ifdef FW_BUILD_WIN
- fUserColorDepth = 0;
- fWinPalette = NULL;
- #endif
-
- PrivReadFromStream(stream, bDIBFileHeader);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::GetPlatformBitmap
- //----------------------------------------------------------------------------------------
-
- FW_PlatformBitmap FW_CPrivBitmapRep::GetPlatformBitmap() const
- {
- return fPlatformBitmap;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::IsPlatformBitmapOrphan
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CPrivBitmapRep::IsPlatformBitmapOrphan() const
- {
- return !fOwnBitmap;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::OrphanPlatformBitmap
- //----------------------------------------------------------------------------------------
-
- FW_PlatformBitmap FW_CPrivBitmapRep::OrphanPlatformBitmap()
- {
- FW_ASSERT(fOwnBitmap); // Only orphan once
- fOwnBitmap = FALSE;
- return fPlatformBitmap;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::SetPlatformBitmap
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::SetPlatformBitmap(FW_PlatformBitmap newBitmap)
- {
- if (fPlatformBitmap != newBitmap)
- {
- PrivDisposeBitmap();
- fPlatformBitmap = newBitmap;
- }
-
- fOwnBitmap = FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::AdoptPlatformBitmap
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::AdoptPlatformBitmap(FW_PlatformBitmap newBitmap)
- {
- SetPlatformBitmap(newBitmap);
- fOwnBitmap = TRUE;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::GetPalette
- //----------------------------------------------------------------------------------------
-
- FW_Palette FW_CPrivBitmapRep::GetPalette() const
- {
- #ifdef FW_BUILD_MAC
- FW_CPrivMacPixelLock lock((FW_HBitmap)this);
- PixMapHandle pmh = lock.GetPixMapHandle();
- return (*pmh)->pmTable;
- #endif
- #ifdef FW_BUILD_WIN
- return fWinPalette;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::SetPalette
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::SetPalette(FW_Palette palette)
- {
- #ifdef FW_BUILD_MAC
- FW_CPrivMacPixelLock lock(this);
- PixMapHandle pmh = lock.GetPixMapHandle();
- CTabHandle oldTable = (*pmh)->pmTable;
- (*pmh)->pmTable = palette;
- ::DisposeHandle((Handle)oldTable);
- #endif
- #ifdef FW_BUILD_WIN
- if (fWinPalette != NULL)
- ::DeleteObject(fWinPalette);
- fWinPalette = palette;
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::GetBitmapInfo
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::GetBitmapInfo(
- short& width,
- short& height,
- short& rowBytes,
- short& pixelSize) const
- {
- #ifdef FW_BUILD_MAC
- PixMapHandle pixMap = ::GetGWorldPixMap(fPlatformBitmap);
-
- width = (*pixMap)->bounds.right - (*pixMap)->bounds.left;
- height = (*pixMap)->bounds.bottom - (*pixMap)->bounds.top;
- rowBytes = (*pixMap)->rowBytes & 0x7FFF;
- pixelSize = (*pixMap)->pixelSize;
- #endif
-
- #ifdef FW_BUILD_WIN
- BITMAP bm;
- ::GetObject(fPlatformBitmap, sizeof(bm), &bm);
-
- width = (short) bm.bmWidth;
- height = (short) bm.bmHeight;
- rowBytes = (short) bm.bmWidthBytes;
- pixelSize = fUserColorDepth; // The actual DDB pixel size may differ
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::GetBitmapBoundsGC
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::GetBitmapBoundsGC(Environment* ev, FW_SGraphicContext& gc, FW_SRect& bounds) const
- {
- short width, height,rowBytes, pixelSize;
- GetBitmapInfo(width, height, rowBytes, pixelSize);
-
- FW_CPoint size;
- FW_PrivGC_DeviceToLogicalSize(ev, gc, width, height, size);
- // let go if error
-
- bounds.left = FW_kFixed0;
- bounds.top = FW_kFixed0;
- bounds.right = size.x;
- bounds.bottom = size.y;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::GetBitmapBounds
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::GetBitmapBounds(FW_SRect& bounds) const
- {
- short width, height,rowBytes, pixelSize;
- GetBitmapInfo(width, height, rowBytes, pixelSize);
-
- bounds.left = FW_IntToFixed(0);
- bounds.top = FW_IntToFixed(0);
- bounds.right = FW_IntToFixed(width);
- bounds.bottom = FW_IntToFixed(height);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::GetPixelColor
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::GetPixelColor(short horiz,
- short vert,
- FW_CColor& color) const
- {
- #ifdef FW_BUILD_MAC
- CGrafPtr curPort;
- GDHandle gdh;
- RGBColor platformColor;
- ::GetGWorld(&curPort, &gdh);
- ::SetGWorld(GetPlatformBitmap(), NULL);
- ::GetCPixel(horiz, vert, &platformColor);
- ::SetGWorld(curPort, gdh);
-
- color = platformColor;
- #endif
-
- #ifdef FW_BUILD_WIN
- // needs to be implemented
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::SetPixelColor
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::SetPixelColor(short horiz,
- short vert,
- const FW_CColor& color)
- {
- #ifdef FW_BUILD_MAC
- CGrafPtr curPort;
- GDHandle gdh;
- RGBColor platformColor(color);
- ::GetGWorld(&curPort, &gdh);
- ::SetGWorld(GetPlatformBitmap(), NULL);
- ::SetCPixel(horiz, vert, &platformColor);
- ::SetGWorld(curPort, gdh);
- #endif
-
- #ifdef FW_BUILD_WIN
- // needs to be implemented
- #endif
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::ChangeBitmap
- //----------------------------------------------------------------------------------------
-
- FW_PlatformError FW_CPrivBitmapRep::ChangeBitmap(short width,
- short height,
- short pixelSize,
- FW_Boolean bScale)
- {
- FW_PlatformError error = FW_xNoError;
-
- #ifdef FW_BUILD_MAC
- FW_ASSERT(!MacIsPixelsLocked());
- FW_CPlatformRect boundsRect(0, 0, width, height);
- GWorldFlags flags = ::UpdateGWorld(&fPlatformBitmap, pixelSize, &boundsRect, NULL, NULL, bScale ? stretchPix : clipPix);
- if (flags == gwFlagErr)
- error = FW_xGraphicException;
- #endif
-
- #ifdef FW_BUILD_WIN
- // Determine color depth for the DDB
- short bmNewPlanes = 1, bmNewBitsPixel = 1;
- if(pixelSize != 1)
- FW_PrivWinGetDisplayColorInfo(bmNewPlanes, bmNewBitsPixel);
-
- // Get the current bitmap depth
- BITMAP bm;
- ::GetObject(fPlatformBitmap, sizeof(bm), &bm);
-
- if(bm.bmPlanes != bmNewPlanes || bm.bmBitsPixel != bmNewBitsPixel ||
- bm.bmWidth != width || bm.bmHeight != height)
- {
- // Create a new bitmap
- HBITMAP bitmap = ::CreateBitmap(width, height, bmNewPlanes, bmNewBitsPixel, NULL);
- if(bitmap != NULL)
- {
- // Copy the bits
- FW_CPlatformRect rectSrc(0, 0, bm.bmWidth, bm.bmHeight);
- FW_CPlatformRect rectDst(0, 0, width, height);
- FW_DDBCopyImage(
- bitmap, NULL, &rectDst, // Even if fWinPalette is not NULL,
- fPlatformBitmap, NULL, &rectSrc, // no color translation is needed here
- bScale
- ? FW_kScaleImage
- : FW_kCropImage);
-
- // Replace the platform bitmap
- AdoptPlatformBitmap(bitmap);
- }
- else
- {
- error = FW_xGraphicException;
- }
- }
-
- // Update the color depth
- if(pixelSize != 0 && error == FW_xNoError)
- fUserColorDepth = pixelSize;
- else
- fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
- #endif
-
- return error;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::ChangeBitmap
- //----------------------------------------------------------------------------------------
-
- FW_PlatformError FW_CPrivBitmapRep::ChangeBitmap(void* image,
- long imageSize,
- short rowBytes,
- short width,
- short height,
- short pixelSize,
- FW_Boolean bScale)
- {
- FW_ASSERT(image != NULL);
- FW_PlatformError error = ChangeBitmap(width, height, pixelSize, bScale);
- if (error == FW_xNoError)
- error = SetImage(image, imageSize, rowBytes);
- return error;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::SetImage
- //----------------------------------------------------------------------------------------
-
- FW_PlatformError FW_CPrivBitmapRep::SetImage(void* image,
- long imageSize,
- short rowBytes)
- {
- short bmpHeight, bmpWidth, bmpRowBytes, bmpPixelSize;
- GetBitmapInfo(bmpWidth, bmpHeight, bmpRowBytes, bmpPixelSize);
-
- FW_ASSERT(rowBytes <= bmpRowBytes);
-
- #ifdef FW_BUILD_MAC
- FW_CPrivMacPixelLock lock(this);
- PixMapHandle pmh = lock.GetPixMapHandle();
- Ptr baseAddr = ::GetPixBaseAddr(pmh);
-
- if (rowBytes == bmpRowBytes)
- {
- size_t toCopy = bmpHeight * bmpRowBytes;
- if (toCopy > imageSize)
- toCopy = imageSize;
-
- FW_PrimitiveCopyMemory(image, baseAddr, toCopy);
- }
- else
- {
- const char* srcPtr = (const char*) image;
- char* dstPtr = baseAddr;
-
- for (
- int nRow = 0;
- nRow < bmpHeight && imageSize > 0;
- ++nRow, imageSize -= rowBytes, srcPtr += rowBytes, dstPtr += bmpRowBytes
- )
- FW_PrimitiveCopyMemory(srcPtr, dstPtr, rowBytes);
- }
- #endif
-
- #ifdef FW_BUILD_WIN
- if (rowBytes == bmpRowBytes)
- {
- ::SetBitmapBits(fPlatformBitmap, imageSize, image);
- }
- else
- {
- int nRowCount = imageSize / rowBytes;
- FW_CAcquireTemporaryMemory tempMem(nRowCount * bmpRowBytes);
-
- const char* srcPtr = (const char*) image;
- char* dstPtr = (char*) tempMem.GetPointer();
-
- for (
- int nRow = 0;
- nRow < bmpHeight && imageSize > 0;
- ++nRow, imageSize -= rowBytes, srcPtr += rowBytes, dstPtr += bmpRowBytes
- )
- FW_PrimitiveCopyMemory(srcPtr, dstPtr, rowBytes);
-
- ::SetBitmapBits(fPlatformBitmap, nRowCount * bmpRowBytes, tempMem.GetPointer());
- }
- #endif
-
- return FW_xNoError;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::CopyPixels
- //----------------------------------------------------------------------------------------
-
- FW_PlatformError FW_CPrivBitmapRep::CopyPixels(FW_CPrivBitmapRep& dstBitmap,
- const FW_SRect& boundsSrc,
- const FW_SRect& boundsDst) const
- {
- FW_RETURN_ERR_TRY
- {
- FW_CPlatformRect plfmSrcRect = boundsSrc;
- FW_CPlatformRect plfmDstRect = boundsDst;
-
- #ifdef FW_BUILD_MAC
- FW_CPrivMacPixelLock srcLock((FW_HBitmap)this);
- PixMapHandle srcPixMap = srcLock.GetPixMapHandle();
-
- FW_CPrivMacPixelLock dstLock(&dstBitmap);
- PixMapHandle dstPixMap = dstLock.GetPixMapHandle();
-
- CGrafPtr curPort;
- GDHandle gdh;
- ::GetGWorld(&curPort, &gdh);
- ::SetGWorld(dstBitmap.GetPlatformBitmap(), NULL);
- ::CopyBits((BitMap*)*srcPixMap, (BitMap*)*dstPixMap,
- &plfmSrcRect, &plfmDstRect,
- srcCopy, NULL);
- ::SetGWorld(curPort, gdh);
- #endif
- #ifdef FW_BUILD_WIN
- HBITMAP dstBitmapHandle = dstBitmap.GetPlatformBitmap();
- HPALETTE hDstPalette = dstBitmap.GetPalette();
-
- FW_DDBCopyImage(dstBitmapHandle, hDstPalette, &plfmDstRect,
- fPlatformBitmap, fWinPalette, &plfmSrcRect,
- FW_kScaleImage);
- #endif
- }
- FW_RETURN_ERR_CATCH
- }
-
- #ifdef FW_BUILD_MAC
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::FW_CPrivBitmapRep
- //----------------------------------------------------------------------------------------
- // From a picture: will own the bitmap
-
- FW_CPrivBitmapRep::FW_CPrivBitmapRep(FW_HPicture picture, FW_SColor fillColor, const FW_SRect& pictPart) :
- fOwnBitmap(TRUE),
- fPlatformBitmap(NULL)
- {
- #ifdef FW_BUILD_MAC
- fLockCount = 0;
- fPixMapHandle = NULL;
- #endif
- #ifdef FW_BUILD_WIN
- fUserColorDepth = 0;
- fWinPalette = NULL;
- #endif
-
- CGrafPtr curPort;
- GDHandle gdh;
- ::GetGWorld(&curPort, &gdh);
-
- // It looks like I have to be in a 'valid' port before calling GetPictInfo
- // I don't know why but if I remove the following three lines I end up with
- // color problems.
- CGrafPtr screenPort;
- GetCWMgrPort(&screenPort);
- ::SetPort((GrafPtr)screenPort);
-
- FW_PlatformPict pictHandle = picture->GetPlatformPict();
- FW_ASSERT(pictHandle != 0);
-
- // Just get picture color depth at first
- PictInfo pictInfo;
- ::GetPictInfo(pictHandle, &pictInfo, 0, 0, 0, 0);
-
- // Now that we know the color depth, we are ready to get the color table
- short nColors = pictInfo.depth > 8 ? 256 : 1 << pictInfo.depth;
- ::GetPictInfo(pictHandle, &pictInfo, returnColorTable, nColors, systemMethod, 0);
-
- // Create a GWorld
- FW_CPlatformRect gworldRect = pictPart;
- ::OffsetRect(&gworldRect, -gworldRect.left, -gworldRect.top);
- QDErr err = ::NewGWorld(&fPlatformBitmap, pictInfo.depth, &gworldRect,
- pictInfo.theColorTable, NULL, useTempMem);
- FW_ASSERT(err == noErr);
-
- ::DisposeCTable(pictInfo.theColorTable);
-
- FW_FailOnError(err);
- if(fPlatformBitmap == NULL)
- {
- ::SetGWorld(curPort, gdh);
- FW_Failure(FW_xGraphicException);
- }
-
- // Copy the image
- ::SetGWorld(fPlatformBitmap, NULL);
-
- FW_CPrivMacPixelLock lock(this);
- // PixMapHandle pmh = lock.GetPixMapHandle();
-
- FW_CColor odfColor = fillColor;
- RGBColor macColor(odfColor);
- ::RGBBackColor(&macColor);
- ::EraseRect(&gworldRect);
-
-
- FW_PrivMacSetStdColors();
- ::PenNormal();
- FW_CPlatformRect rectPicture = pictInfo.sourceRect;
- ::OffsetRect(&rectPicture, - FW_FixedToInt(pictPart.left), - FW_FixedToInt(pictPart.top));
- ::DrawPicture(pictHandle, &rectPicture);
-
- ::SetGWorld(curPort, gdh);
-
- FW_END_CONSTRUCTOR
- }
- #endif
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::MacGetAsPicture
- //----------------------------------------------------------------------------------------
-
- FW_HPicture FW_CPrivBitmapRep::MacGetAsPicture(const FW_SRect& bounds) const
- {
- CGrafPtr curPort;
- GDHandle gdh;
- ::GetGWorld(&curPort, &gdh);
-
- FW_CPrivMacPixelLock lock((FW_HBitmap)this);
- PixMapHandle pixMap = lock.GetPixMapHandle();
-
- GDHandle gdevice = ::GetGWorldDevice(fPlatformBitmap);
-
- ::SetGWorld(fPlatformBitmap, gdevice);
-
- FW_CPlatformRect plfmSrcRect = bounds;
- FW_CPlatformRect plfmDstRect = bounds;
- ::OffsetRect(&plfmDstRect, -plfmDstRect.left, -plfmDstRect.top);
-
- OpenCPicParams openParams;
- openParams.srcRect = plfmDstRect;
- openParams.hRes =
- openParams.vRes = 0x00480000;
- openParams.version = -2;
- openParams.reserved1 =
- openParams.reserved2 = 0;
-
- PicHandle hPict = ::OpenCPicture(&openParams);
- ::CopyBits((BitMap*)*pixMap, (BitMap*)*pixMap,
- &plfmSrcRect, &plfmDstRect,
- srcCopy, NULL);
- ::ClosePicture();
-
- ::SetGWorld(curPort, gdh);
-
- return FW_NEW(FW_CPrivPictureRep, (hPict));
- }
-
- #endif
-
- #ifdef FW_BUILD_MAC
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::MacLockPixels
- //----------------------------------------------------------------------------------------
-
- PixMapHandle FW_CPrivBitmapRep::MacLockPixels()
- {
- if (++ fLockCount == 1)
- {
- FW_ASSERT(fPixMapHandle == NULL);
- fPixMapHandle = ::GetGWorldPixMap(fPlatformBitmap);
- ::LockPixels(fPixMapHandle);
- }
-
- return fPixMapHandle;
- }
- #endif
-
- #ifdef FW_BUILD_MAC
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::MacUnlockPixels
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::MacUnlockPixels()
- {
- FW_ASSERT(fPixMapHandle != NULL);
- FW_ASSERT(fLockCount != 0);
-
- if (-- fLockCount == 0)
- {
- ::UnlockPixels(fPixMapHandle);
- fPixMapHandle = NULL;
- }
- }
- #endif
-
- #ifdef FW_BUILD_MAC
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::MacIsPixelsLocked
- //----------------------------------------------------------------------------------------
-
- FW_Boolean FW_CPrivBitmapRep::MacIsPixelsLocked() const
- {
- return fLockCount != 0;
- }
- #endif
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::PrivDisposeBitmap
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::PrivDisposeBitmap()
- {
- if (fOwnBitmap && fPlatformBitmap != NULL)
- {
- #ifdef FW_BUILD_MAC
- ::DisposeGWorld(fPlatformBitmap);
- #endif
- #ifdef FW_BUILD_WIN
- ::DeleteObject(fPlatformBitmap);
-
- if (fWinPalette != NULL)
- {
- ::DeleteObject(fWinPalette);
- fWinPalette = NULL;
- }
- #endif
- }
-
- fPlatformBitmap = NULL;
- fOwnBitmap = FALSE;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::PrivMakeBitmap
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::PrivMakeBitmap(
- short width, short height,
- short pixelSize, FW_Palette palette)
- {
- FW_PlatformBitmap bitmap = NULL;
-
- FW_ASSERT(height != 0);
- FW_ASSERT(width != 0);
-
- #ifdef FW_BUILD_MAC
- FW_CPlatformRect boundsRect(0, 0, width, height);
-
- OSErr err = ::NewGWorld(&bitmap, pixelSize, &boundsRect, palette, NULL, useTempMem);
- FW_FailOnError(err);
- #endif
- #ifdef FW_BUILD_WIN
- // Determine color depth for the DDB
- short bmPlanes = 1, bmBitsPixel = 1;
- if(pixelSize != 1)
- FW_PrivWinGetDisplayColorInfo(bmPlanes, bmBitsPixel);
-
- // Create the bitmap
- bitmap = ::CreateBitmap(width, height, bmPlanes, bmBitsPixel, NULL);
- if(bitmap == NULL)
- FW_Failure(FW_xMemoryExhausted);
-
- // Update the color depth
- if(pixelSize != 0)
- fUserColorDepth = pixelSize;
- else
- fUserColorDepth = FW_DDBGetColorDepth(bitmap);
-
- // Copy the palette if there is one
- if (palette != NULL)
- fWinPalette = FW_CopyPalette(palette);
- #endif
-
- fPlatformBitmap = bitmap;
- fOwnBitmap = TRUE;
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivBitmapRep::PrivReadFromStream
- //----------------------------------------------------------------------------------------
-
- void FW_CPrivBitmapRep::PrivReadFromStream(FW_CReadableStream& stream, FW_Boolean bDIBFileHeader)
- {
- #ifdef FW_BUILD_WIN
- FW_WinDIB dib = FW_DIBLoadFromStream(stream, bDIBFileHeader);
-
- // Get the palette
- fWinPalette = FW_DIBGetPalette(dib);
-
- FW_TRY
- {
- fPlatformBitmap = FW_DIBConvertToBitmap(dib, fWinPalette);
- }
- FW_CATCH_BEGIN
- FW_CATCH_EVERYTHING()
- {
- FW_DIBFree(dib);
- FW_THROW_SAME();
- }
- FW_CATCH_END
-
- FW_DIBFree(dib);
-
- // Update the color depth
- fUserColorDepth = FW_DDBGetColorDepth(fPlatformBitmap);
- #endif
-
- #ifdef FW_BUILD_MAC
- // Read the BITMAPFILEINFO header
- if(bDIBFileHeader)
- {
- BITMAPFILEHEADER bmfh;
-
- stream.Read((void*) &bmfh, sizeof(bmfh));
-
- MacRepackValue(&bmfh.bfType);
- MacRepackValue(&bmfh.bfSize);
- MacRepackValue(&bmfh.bfReserved1);
- MacRepackValue(&bmfh.bfReserved2);
- MacRepackValue(&bmfh.bfOffBits);
-
- if(bmfh.bfType != FW_kWinBitmapSignature || bmfh.bfReserved1 != 0 || bmfh.bfReserved2 != 0)
- FW_Failure(FW_xInvalidBitmapData);
- }
-
- // Start reading the header
- FW_Boolean bIsWindowsBitmap;
- BITMAPINFOHEADER bmih;
-
- stream.Read((void*) &bmih.biSize, sizeof(bmih.biSize));
-
- MacRepackValue(&bmih.biSize);
-
- if(bmih.biSize == sizeof(BITMAPINFOHEADER)) // Windows bitmap
- {
- // Read the Windows header
- stream.Read((void*) &bmih.biWidth, sizeof(bmih) - sizeof(bmih.biSize));
-
- MacRepackValue(&bmih.biWidth);
- MacRepackValue(&bmih.biHeight);
- MacRepackValue(&bmih.biPlanes);
- MacRepackValue(&bmih.biBitCount);
- MacRepackValue(&bmih.biCompression);
- MacRepackValue(&bmih.biSizeImage);
- MacRepackValue(&bmih.biXPelsPerMeter);
- MacRepackValue(&bmih.biYPelsPerMeter);
- MacRepackValue(&bmih.biClrUsed);
- MacRepackValue(&bmih.biClrImportant);
-
- bIsWindowsBitmap = TRUE;
- }
- else if(bmih.biSize == sizeof(BITMAPCOREHEADER)) // OS/2 bitmap
- {
- // Read the OS/2 header
- BITMAPCOREHEADER bmch;
-
- stream.Read((void* )&bmch.bcWidth, sizeof(bmch) - sizeof(bmch.bcSize));
-
- MacRepackValue(&bmch.bcWidth);
- MacRepackValue(&bmch.bcHeight);
- MacRepackValue(&bmch.bcPlanes);
- MacRepackValue(&bmch.bcBitCount);
-
- // Plug the data into the Windows header
- bmih.biWidth = bmch.bcWidth;
- bmih.biHeight = bmih.biHeight;
- bmih.biPlanes = bmch.bcPlanes;
- bmih.biBitCount = bmch.bcBitCount;
- bmih.biCompression = 0;
- bmih.biSizeImage = 0;
- bmih.biXPelsPerMeter = 0;
- bmih.biYPelsPerMeter = 0;
- bmih.biClrUsed = 0;
- bmih.biClrImportant = 0;
-
- bIsWindowsBitmap = FALSE;
- }
- else
- FW_Failure(FW_xInvalidBitmapData);
-
- // Check for compression flag -- we don't support it!
- if(bmih.biCompression != 0)
- FW_Failure(FW_xInvalidBitmapData);
-
- // Determine the size of the color table
- short bitDepth = bmih.biBitCount;
- short colorCount = bmih.biClrUsed != 0 ? bmih.biClrUsed : bitDepth >= 16 ? 0 : (1 << bitDepth);
-
- // Read the color table
- CTabHandle colorTabHandle = NULL;
- if(colorCount != 0)
- {
- Size colorTableSize = sizeof(ColorTable) + sizeof(ColorSpec) * (colorCount - 1);
- FW_CAcquireTemporarySystemHandle colorTableMemory(colorTableSize);
- CTabPtr colorTablePtr = (CTabPtr) colorTableMemory.GetPointer();
-
- for(int i = 0; i < colorCount; colorTablePtr->ctTable[i].value = i, ++i)
- {
- if(bIsWindowsBitmap)
- {
- RGBQUAD quad;
- stream.Read((void*) &quad, sizeof(quad));
-
- colorTablePtr->ctTable[i].rgb.red = (quad.rgbRed << 8) | quad.rgbRed;
- colorTablePtr->ctTable[i].rgb.green = (quad.rgbGreen << 8) | quad.rgbGreen;
- colorTablePtr->ctTable[i].rgb.blue = (quad.rgbBlue << 8) | quad.rgbBlue;
- }
- else
- {
- RGBTRIPLE trip;
- stream.Read((void*) &trip, sizeof(trip));
-
- colorTablePtr->ctTable[i].rgb.red = trip.rgbtRed << 8;
- colorTablePtr->ctTable[i].rgb.green = trip.rgbtGreen<< 8;
- colorTablePtr->ctTable[i].rgb.blue = trip.rgbtBlue << 8;
- }
- }
-
- colorTablePtr->ctSeed = 0;
- colorTablePtr->ctFlags = 0;
- colorTablePtr->ctSize = colorCount - 1;
-
- colorTabHandle = (CTabHandle) colorTableMemory.Orphan();
-
- ::CTabChanged(colorTabHandle);
- }
-
- // Create a GWorld
- FW_CPlatformRect bounds(0, 0, bmih.biWidth, bmih.biHeight);
- OSErr err = ::NewGWorld(&fPlatformBitmap, bitDepth, &bounds,
- colorTabHandle, NULL, useTempMem);
-
- if (colorTabHandle != NULL)
- ::DisposeCTable(colorTabHandle);
-
- FW_FailOnError(err);
-
- // Lock the memory pixmap
- FW_CPrivMacPixelLock lock(this);
- PixMapHandle memPixMap = lock.GetPixMapHandle();
- void* memBaseAddr = ::GetPixBaseAddr(memPixMap);
-
- // Read the bits
- short resRowBytes = ((bmih.biWidth * bitDepth + 31) & ~31) / 8;
- short memRowBytes = (*memPixMap)->rowBytes & 0x7FFF;
- FW_ASSERT(resRowBytes <= memRowBytes);
-
- char* curBuffer = (char*) memBaseAddr + (bmih.biHeight - 1) * memRowBytes;
-
- for(int row = bmih.biHeight - 1; row >= 0; -- row, curBuffer -= memRowBytes)
- {
- // Read and repack the next row
- stream.Read(curBuffer, resRowBytes);
- MacRepackResourceRow(curBuffer, bitDepth, resRowBytes);
- }
- #endif
- }
-
- #ifdef FW_BUILD_MAC
-
- //========================================================================================
- // CLASS FW_CPrivMacPixelLock
- //========================================================================================
-
- FW_DEFINE_AUTO(FW_CPrivMacPixelLock)
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivMacPixelLock::FW_CPrivMacPixelLock
- //----------------------------------------------------------------------------------------
-
- FW_CPrivMacPixelLock::FW_CPrivMacPixelLock(FW_HBitmap rep) :
- fBitmap(rep)
- {
- fPixMapHandle = FW_PrivBitmap_MacLockPixels(fBitmap);
-
- FW_END_CONSTRUCTOR
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivMacPixelLock::~FW_CPrivMacPixelLock
- //----------------------------------------------------------------------------------------
-
- FW_CPrivMacPixelLock::~FW_CPrivMacPixelLock()
- {
- FW_START_DESTRUCTOR
-
- FW_PrivBitmap_MacUnlockPixels(fBitmap);
- }
-
- //----------------------------------------------------------------------------------------
- // FW_CPrivMacPixelLock::GetPixMapHandle
- //----------------------------------------------------------------------------------------
-
- PixMapHandle FW_CPrivMacPixelLock::GetPixMapHandle() const
- {
- return fPixMapHandle;
- }
-
- #endif
-